package com.angel.shiro;

import com.angel.bean.UserInfo;
import com.angel.service.UserInfoService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;

/***
 * 用户登录的，对应userInfo表
 * @author Rabit
 */

public class UserAuthorizingRealm extends AuthorizingRealm {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private UserInfoService userInfoService;

    /**
     * 获取权限授权信息，如果缓存中存在，则直接从缓存中获取，否则就重新获取， 登录成功后调用
     */
    @Override
    protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("-------------");
        if (principals == null) {
            return null;
        }
        //这里可以设置缓存，从缓存中读取
        return doGetAuthorizationInfo(principals);
    }

    /**
     * 授权查询回调函数,进行鉴权但缓存中无用户的授权信息时调用
     * 多realm该方法会在多个realm之间调用，所以需要判断当前用户是否是当前类中的shiroUser对象[其他realm一样]
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        if (principals == null) {
            return null;
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermission("user");
        // 判断是否是当前用户登录的对象
        this.logger.info("----------a a a USER---:回调");
        return info;
    }

    /**
     * 身份验证回调函数,登录时调用
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UserNamePasswordToken token = (UserNamePasswordToken) authenticationToken;
        //判断用户登录类型
        if (token.getUserType().equals("1")) {
//            vip用户实现登录逻辑
            UserInfo userInfo = new UserInfo();
            userInfo.setUserTel(token.getUsername());
            userInfo.setPassword(new String(token.getPassword()));
            userInfo = userInfoService.findOne(userInfo);

            if (userInfo != null) {
                this.logger.info("----------成功登录---:登录了");
                return new SimpleAuthenticationInfo(new Principal(userInfo), token.getPassword(), getName());
            }
        }
        //具体登录判断逻辑
        return null;
    }

    /**
     * 授权用户信息
     */
    public static class Principal implements Serializable {

        private static final long serialVersionUID = 6977402643848374752L;
        private int type;
        private String name;
        private Integer id;
        private String username;
        private UserInfo userInfo;

        public Principal(UserInfo user) {
            this.id = user.getId();
            this.name = user.getUserName();
            this.username = user.getUserTel();
            this.type = 1;
            this.userInfo = user;
        }

        public Integer getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public int getType() {
            return type;
        }

        public String getUsername() {
            return username;
        }

        public UserInfo getUserInfo() {
            return userInfo;
        }

        @Override
        public String toString() {
            return "Principal{" +
                    "id=" + id +
                    '}';
        }
    }
}
